<?php
set_include_path("../include;include");
require_once '/util/globals.php';
require_once '/dao/Database.php';
require_once '/model/Event.php';
require_once '/model/Supplement.php';


/**
 * database access class for Supplement
 *
 * @author Thomas Crepain <contact@thomascrepain.be>
 */
class SupplementDAO
{
        const TABLENAME = 'supplement';
        const PARTICIPANT_REGISTRATION_SUPPLEMENT_TABLENAME = 'participant_registration_supplement';

	/**
	 *
	 *
	 * @var Database
	 */
	private $db;

	/**
	 * Contains the supplement cache
	 *
	 * @var array
	 */
	private $supplementCache = array();

	/**
	 * unique instance of this class
	 * Singleton pattern
	 *
	 * @var Database
	 */
	private static $uniqueInstance;


	/**
	 * constructs the DAO
	 */
	private function __construct()
	{
		// get database
                $this->db = Database::getInstance();
	}

	/**
	 * gets instance of database
	 *
	 * @return SupplementDAO
	 */
	public static function getInstance()
	{
		if(!isset(self::$uniqueInstance))
		{
			self::$uniqueInstance = new self();
		}

		return self::$uniqueInstance;
	}

        /**
	 * Returns the event_id
	 *
	 * @return integer
	 */
	public function getEventIdBySupplementId(integer $SupplementId)
	{
		// build cache
		$this->buildCache($SupplementId);

		return (integer) $this->supplementCache[$SupplementId]['event_id'];
	}

	/**
	 * Returns the name
	 *
	 * @return String
	 */
	public function getNameBySupplementId(integer $SupplementId)
	{
		// build cache
		$this->buildCache($SupplementId);

		return $this->supplementCache[$SupplementId]['name'];
	}

        /**
	 * Returns the description
	 *
	 * @return String
	 */
	public function getDescriptionBySupplementId(integer $SupplementId)
	{
		// build cache
		$this->buildCache($SupplementId);

		return $this->supplementCache[$SupplementId]['description'];
	}

        /**
	 * Returns the cost
	 *
	 * @return double
	 */
	public function getCostBySupplementId(integer $SupplementId)
	{
		// build cache
		$this->buildCache($SupplementId);

		return (double) $this->supplementCache[$SupplementId]['cost'];
	}

        /**
         * Returns every supplement for the given participant and registration
         *
         * @param integer $participantId
         * @param integer $registrationId
         * @return array of supplements
         */
        public function getAllSupplementsFor(integer $participantId, integer $registrationId)
        {
            $supplements = array();

            // Get all records for both id's
            $records = (array) $this->db->getRecords("SELECT s.supplement_id, s.event_id, s.name, s.description, s.cost
                                                FROM " . self::PARTICIPANT_REGISTRATION_SUPPLEMENT_TABLENAME . " AS prs
                                                INNER JOIN ".self::TABLENAME." AS s ON prs.Supplement_id = s.Supplement_id
                                                WHERE prs.participant_registration_participant_id = ? AND prs.participant_registration_registration_id = ?",
                                                array($participantId, $registrationId));

            // for every retrieved record...
            foreach ($records as $record) {
                // Put every record in the SupplementCache
                $this->supplementCache[$record['supplement_id']] = $record;

                // Make a supplement object from every record
                $event = Event::loadEvent((integer) $record['event_id']);
                $supplement = Supplement::createNew($record['description'], $event, $record['name'], (double) $record['cost']);
                $supplement->setId((integer) $record['supplement_id']);
                $supplements[] = $supplement;
            }

            // Return an array of those supplement objects
            return $supplements;
        }

        /**
         * Returns every supplement for the given participant and registration
         *
         * @param Event $event
         * @return array of supplements
         */
        public function getAllSupplementsOf(Event $event)
        {
            $supplements = array();

            // Get all records for both id's
            $records = (array) $this->db->getRecords("SELECT s.supplement_id, s.event_id, s.name, s.description, s.cost
                                                FROM ".self::TABLENAME." AS s
                                                WHERE s.event_id = ?",
                                                array($event->getId()));

            // for every retrieved record...
            foreach ($records as $record) {
                // Put every record in the SupplementCache
                $this->supplementCache[$record['supplement_id']] = $record;

                // Make a supplement object from every record
                $supplement = Supplement::createNew($record['description'], $event, $record['name'], (double) $record['cost']);
                $supplement->setId((integer) $record['supplement_id']);
                $supplements[] = $supplement;
            }

            // Return an array of those supplement objects
            return $supplements;
        }

        /**
         * Links a participant to a registration with wa price category
         *
         * @param Participant $Participant
         * @param Registration $registration
         * @param PriceCategory $priceCategory
         */
        public function linkSupplementToParticipantAndRegistration(Supplement $supplement, Participant $participant, Registration $registration){
            $this->db->insert(self::PARTICIPANT_REGISTRATION_SUPPLEMENT_TABLENAME, array('participant_registration_participant_id' => $participant->getId(),
                                                                                'participant_registration_registration_id' => $registration->getId(),
                                                                                'supplement_id' => $supplement->getId()));
        }


	/**
	 * Build the cache for the SupplementId if needed
	 *
	 * @param integer	$SupplementId
	 */
	private function buildCache(integer $SupplementId)
	{
		// if cache is not build
		if(!isset($this->supplementCache[$SupplementId]))
		{
                    // fill cache with this Supplement
                    $this->supplementCache[$SupplementId] = $this->db->getRecord("SELECT s.supplement_id, s.event_id, s.name, s.description, s.cost
                                                                            FROM ".self::TABLENAME." AS s
                                                                            WHERE s.supplement_id = ?",
                                                                            array($SupplementId));
		}
	}


        /**
         * Saves the given member in the database
         *
         * @param Supplement $Supplement
         * @return integer $id  id in database
         */
        public function save(Supplement $Supplement){
            $id = 0;

            // is this a new member?
            if(is_null($Supplement->getId())){
                $id = $this->db->insert(self::TABLENAME, array(
                        'event_id' => $Supplement->getEvent()->getId(),
                        'name' => $Supplement->getName(),
                        'description' => $Supplement->getDescription(),
                        'cost' => $Supplement->getPrice()));
            } else {
                $id = $Supplement->getId();

                $this->db->update(self::TABLENAME, array(
                        'event_id' => $Supplement->getEvent()->getId(),
                        'name' => $Supplement->getName(),
                        'description' => $Supplement->getDescription(),
                        'cost' => $Supplement->getPrice()));
            }

            return $id;
        }
}

?>